package com.platform.gateway.security;

//import com.alibaba.fastjson.JSONObject;
//import com.alibaba.nacos.common.utils.StringUtils;
//import com.platform.gateway.util.FilterUtils;
//import com.platform.gateway.util.RSAUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
//import org.springframework.cloud.gateway.filter.factory.rewrite.CachedBodyOutputMessage;
//import org.springframework.cloud.gateway.support.BodyInserterContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
//import org.springframework.core.io.buffer.DataBuffer;
//import org.springframework.http.HttpHeaders;
//import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
//import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
//import org.springframework.web.reactive.function.BodyInserter;
//import org.springframework.web.reactive.function.BodyInserters;
//import org.springframework.web.reactive.function.server.HandlerStrategies;
//import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
//import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
//import javax.crypto.BadPaddingException;
//import javax.crypto.IllegalBlockSizeException;
//import javax.crypto.NoSuchPaddingException;
//import java.lang.reflect.Field;
//import java.net.URI;
//import java.security.InvalidKeyException;
//import java.security.NoSuchAlgorithmException;
//import java.security.spec.InvalidKeySpecException;
//import java.util.stream.Collectors;

//import static com.platform.gateway.constant.BusinessConstant.LOGIN_PATH;

/**
 * 网关过滤器：门户网站过滤器
 *
 * @author： yuanlai
 * @description  门户网站过滤器。该过滤器用来在请求头中添加当前服务名称
 */
//@Component
@Configuration
@Slf4j
public class PortalFilter implements GlobalFilter, Ordered {

    @Value("${spring.application.name}")
    private String applicationName;

    @SneakyThrows
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        // 验证token，如果是登录或者非后台不校验Token
//        String requestUrl = exchange.getRequest().getPath().value();
//        String userType = exchange.getRequest().getHeaders().getFirst(UserConstant.USER_TYPE);
//        AntPathMatcher pathMatcher = new AntPathMatcher();
//        if (!pathMatcher.match(LOGIN_PATH, requestUrl) && "admin".equalsIgnoreCase(userType)) {
//            String token = exchange.getRequest().getHeaders().getFirst(UserConstant.TOKEN);
//            Claims claim = TokenUtils.getClaim(token);
//            if (StringUtils.isBlank(token) || claim == null) {
//                return FilterUtils.invalidToken(exchange);
//            }
//        }

        ServerHttpRequest request = exchange.getRequest().mutate()
                .header("serviceName", applicationName)
                .build();
        exchange = exchange.mutate().request(request).build();
        return chain.filter(exchange);

        //return rsaFilter(exchange, chain);
    }

    @Override
    public int getOrder() {
        return -1;
        //return Integer.MIN_VALUE;
    }

//    /**
//     * 拦截请求，rsa解密参数
//     * @param exchange xxx
//     * @param chain XXx
//     * @return xxx
//     */
//    private Mono rsaFilter(ServerWebExchange exchange, GatewayFilterChain chain) {
//
//        MediaType mediaType = exchange.getRequest().getHeaders().getContentType();
//        //isCompatibleWith方法：检查此程序包的规范版本是否与指定版本兼容
//        if(!(MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)
//                || MediaType.APPLICATION_JSON_UTF8.isCompatibleWith(mediaType))) {
//            return chain.filter(exchange);
//        }
//
//        try {
//            updateRequestParam(exchange);
//        } catch (Exception e) {
//            e.printStackTrace();
//            return FilterUtils.invalidUrl(exchange);
//        }
//
//        ServerRequest serverRequest = ServerRequest.create(exchange, HandlerStrategies.withDefaults().messageReaders());
//
//        Mono<String> modifiedBody = serverRequest.bodyToMono(String.class)
//                .flatMap(body -> {
//                    JSONObject jsonObject = JSONObject.parseObject(body);
//                    String param = "";
//                    try {
//                        param = RSAUtils.decrypt(jsonObject.getString("param"), RSAUtils.PRIVATE_KEY);
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                    return Mono.just(param);
//                });
//
//        BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class);
//        HttpHeaders headers = new HttpHeaders();
//        headers.putAll(exchange.getRequest().getHeaders());
//        headers.remove(HttpHeaders.CONTENT_LENGTH);
//
//        CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
//        return bodyInserter.insert(outputMessage,  new BodyInserterContext())
//                .then(Mono.defer(() -> {
//                    ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(exchange.getRequest()) {
//                        @Override
//                        public HttpHeaders getHeaders() {
//                            long contentLength = headers.getContentLength();
//                            HttpHeaders httpHeaders = new HttpHeaders();
//                            httpHeaders.putAll(super.getHeaders());
//                            if (contentLength > 0) {
//                                httpHeaders.setContentLength(contentLength);
//                            } else {
//                                httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
//                            }
//                            return httpHeaders;
//                        }
//
//                        @Override
//                        public Flux<DataBuffer> getBody() {
//                            return outputMessage.getBody();
//                        }
//                    };
//                    return chain.filter(exchange.mutate().request(decorator).build());
//                }));
//    }

//    /**
//     * 修改前端传的Get参数
//     */
//    private void updateRequestParam(ServerWebExchange exchange)
//            throws NoSuchFieldException, IllegalAccessException, NoSuchPaddingException, NoSuchAlgorithmException,
//            IllegalBlockSizeException, BadPaddingException, InvalidKeyException, InvalidKeySpecException {
//        URI uri = exchange.getRequest().getURI();
//        String query = uri.getQuery();
//        String[] split;
//        if (StringUtils.isNotBlank(query)
//                && query.contains("param")
//                && (split = query.split("=")).length > 0) {
//            String param = RSAUtils.decrypt(split[1], RSAUtils.PRIVATE_KEY);
//            Field targetQuery = uri.getClass().getDeclaredField("query");
//            targetQuery.setAccessible(true);
//            targetQuery.set(uri, getParams(param));
//        }
//    }

//    private String getParams(String query) {
//        JSONObject jsonObject = JSONObject.parseObject(query);
//        return jsonObject.entrySet()
//                .stream()
//                .map(e -> e.getKey() + "=" + e.getValue())
//                .collect(Collectors.joining("&"));
//    }

}